import React, {Fragment, useCallback, useRef, useState} from 'react';
import Node from "@/pages/WorkFlowDesigner/Node";
import Zoom from "@/pages/WorkFlowDesigner/Zoom";
import "@/css/workflow.less"
import './index.less'

/**
 * 审批流程画布
 * 画布中包含画面放大缩小功能
 * 画布上审核节点, 在初始条件中添加初始节点画布,流程设置应该展示不同的节点
 */
function toDecimal(x: number) {
    return Math.round(x * 10) / 10;
}

export interface IPosition {
    x: number;
    y: number;
    scrollLeft: number;
    scrollTop: number;
}

export default React.memo(() => {
    // 放大缩小
    const [zoom, setZoom] = useState(1)
    // 滚动
    const [scrolled, setScrolled] = useState(false)
    // 鼠标位置
    const [mousePressedPoint, setMousePressedPoint] = useState<IPosition>()
    // 画布ref
    const canvasRef = useRef<HTMLDivElement>(null)

    const handleZoomIn = useCallback(() => {
        setZoom(zoom => toDecimal(zoom < 3 ? (zoom + 0.1) : zoom))
    }, [])
    //
    const handleZoomOut = useCallback(() => {
        setZoom(zoom => toDecimal(zoom > 0.1 ? (zoom - 0.1) : zoom))
    }, [])

    // 点击鼠标
    const handleMouseDown = useCallback((e: React.MouseEvent) => {
        // 逻辑与
        canvasRef.current && setMousePressedPoint({
            x: e.clientX,
            y: e.clientY,
            scrollLeft: canvasRef.current.scrollLeft,
            scrollTop: canvasRef.current.scrollTop
        })
    }, [])
    // 松开鼠标
    const handleMouseUp = useCallback(() => {
        setMousePressedPoint(undefined)
    }, [])
    // 鼠标移动
    const handleMouseMove = useCallback((e: React.MouseEvent) => {
        if (!mousePressedPoint) {
            return
        }

        const dragMoveDiff = {
            x: mousePressedPoint.x - e.clientX,
            y: mousePressedPoint.y - e.clientY
        }

        if (canvasRef.current) {
            canvasRef.current.scrollLeft = mousePressedPoint.scrollLeft + dragMoveDiff.x;
            canvasRef.current.scrollTop = mousePressedPoint.scrollTop + dragMoveDiff.y;
        }

    }, [mousePressedPoint])
    // 滚动鼠标
    const handleScroll = useCallback((e: React.UIEvent<HTMLElement>) => {
        if (e.currentTarget.scrollTop > 60 || e.currentTarget.scrollLeft > 60) {
            setScrolled(true)
        } else {
            setScrolled(false)
        }
    }, [])


    return (
        <Fragment>
            <div className="col-flex-container">
                <div className="row-flex-container-flex-end zoom">
                    <Zoom
                        float={scrolled}
                        zoom={zoom}
                        onZoomIn={handleZoomIn}
                        onZoomOut={handleZoomOut}
                    />
                </div>
            </div>

            <div className="canvas-container">
                <div className="canvas"
                     style={{
                         cursor: mousePressedPoint ? "grabbing" : "grab"
                     }}
                     ref={canvasRef}
                     draggable={false}
                     onMouseDown={handleMouseDown}
                     onMouseUp={handleMouseUp}
                     onMouseMove={handleMouseMove}
                     onMouseLeave={handleMouseUp}
                     onScroll={handleScroll}
                >
                    <div className="canvas-inner">
                        <div style={{transform: `scale(${zoom})`}}>
                            <Node/>
                        </div>
                    </div>

                </div>

            </div>
        </Fragment>
    )
})
